package com.three.common.message.base;

import com.google.protobuf.InvalidProtocolBufferException;
import com.three.api.connection.Connection;
import com.three.api.protocol.JsonPacket;
import com.three.api.protocol.Packet;
import com.three.api.push.MsgType;
import com.three.protocol.BaseModule;
import io.netty.channel.ChannelFutureListener;

import java.util.Collections;
import java.util.Map;

import static com.three.protocol.CommandEnum.Command.PUSH;

/**
 * msgId、msgType 必填
 * msgType=1 :nofication,提醒。
 * 必填:title，content。没有title，则为应用名称。
 * 非必填。nid 通知id,主要用于聚合通知。
 * content 为push  message。附加的一些业务属性，都在里边。json格式
 * msgType=2 :非通知消息。不在通知栏展示。
 * 必填：content。
 * msgType=3 :消息+提醒
 * 作为一个push消息过去。和jpush不一样。jpush的消息和提醒是分开发送的。
 *
 * Created by mathua on 2017/5/26.
 */
public final class PushMessage extends BaseMessage {

    private MsgType msgType; //type
    private String msgId; //返回使用
    private String content; //content

    public PushMessage(Packet packet, Connection connection) {
        super(packet, connection);
    }

    public static PushMessage build(Connection connection) {
        if (connection.getSessionContext().isSecurity()) {
            return new PushMessage(new Packet(PUSH, genSessionId()), connection);
        } else {
            return new PushMessage(new JsonPacket(PUSH, genSessionId()), connection);
        }
    }

    @Override
    public void decode(byte[] body) throws InvalidProtocolBufferException {
        BaseModule.PushMsg_13 bodyData = BaseModule.PushMsg_13.parseFrom(body);
        msgType = MsgType.valueOf(bodyData.getMsgType().getNumber());
        content = bodyData.getContent();
        if(bodyData.hasMsgId()) {
            msgId = bodyData.getMsgId();
        }
    }

    @Override
    public byte[] encode() {
        BaseModule.PushMsg_13.Builder builder = BaseModule.PushMsg_13.newBuilder();
        builder.setContent(content);
        builder.setMsgType(BaseModule.MsgType.valueOf(msgType.getValue()));
        if(msgId != null) {
            builder.setMsgId(msgId);
        }
        return builder.build().toByteArray();
    }

    @Override
    public void decodeJsonBody(Map<String, Object> body) {
        String content = (String) body.get("content");
        if (content != null) {
            this.content = content;
        }
    }

    @Override
    public Map<String, Object> encodeJsonBody() {
        if (content != null) {
            return Collections.singletonMap("content", content);
        }
        return null;
    }

    public boolean autoAck() {
        return packet.hasFlag(Packet.FLAG_AUTO_ACK);
    }

    public boolean needAck() {
        return packet.hasFlag(Packet.FLAG_BIZ_ACK) || packet.hasFlag(Packet.FLAG_AUTO_ACK);
    }

    public PushMessage setContent(String content) {
        this.content = content;
        return this;
    }

    public PushMessage setMsgType(MsgType msgType) {
        this.msgType = msgType;
        return this;
    }

    @Override
    public void send(ChannelFutureListener listener) {
        super.send(listener);
        this.content = null;//释放内存
    }

    @Override
    public String toString() {
        return "PushMessage{" +
                "content='" + content + '\'' +
                ", packet=" + packet +
                '}';
    }

    public String getContent() {
        return content;
    }
}
